#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct Node{
    int x1,y1,x2,y2;
    bool flag;
    Node(){}
    Node(int a,int b,int c,int d,bool e){
        x1 = a,y1 = b,x2 = c,y2 = d,flag = e;
    }
    int area(){
        if(!flag) return 0;
        return (y2 - y1) * (x2 - x1);
    }
}node[maxn],left[maxn],right[maxn],res[maxn];
struct TNode
{
    int left, right, data, buff;
};

struct Rect
{
    int x1, x2, y1, y2;
}r[ 1000 ];

TNode h[ 2 ][ 20001 * 4 ];
int pos;
int n;

void add( TNode *h, int p, int left, int right )
{
    if ( left < h[ p ].left )
        left = h[ p ].left;
    if ( right > h[ p ].right )
        right = h[ p ].right;
    if ( right < h[ p ].left || left > h[ p ].right )
        return ;
    h[ p ].data += right - left + 1;
    if ( left == h[ p ].left && right == h[ p ].right )
    {
        if ( p * 2 < pos * 2 )
        {
            h[ p * 2 ].buff++;
            h[ p * 2 + 1 ].buff++;
        }
    }
    else
    {
        add( h, p * 2, left, right );
        add( h, p * 2 + 1, left, right );
    }
}

int query( TNode *h, int p, int left, int right )
{
    if ( left < h[ p ].left )
        left = h[ p ].left;
    if ( right > h[ p ].right )
        right = h[ p ].right;
    if ( right < h[ p ].left || left > h[ p ].right )
        return 0;
    if ( p * 2 < pos * 2 )
    {
        h[ p * 2 ].buff += h[ p ].buff;
        h[ p * 2 + 1 ].buff += h[ p ].buff;
    }
    h[ p ].data += h[ p ].buff * ( right - left + 1 );
    h[ p ].buff = 0;
    if ( left == h[ p ].left && right == h[ p ].right )
        return h[ p ].data;
    return query( h, p * 2, left, right ) + query( h, p * 2 + 1, left, right );
}

void init( )
{
    int i, j;
    scanf("%d", &n);
    for ( i = 0; i < n; i++ )
    {
        scanf("%d%d%d%d", &r[ i ].x1, &r[ i ].y1, &r[ i ].x2, &r[ i ].y2);
        r[ i ].x1 += 10000; r[ i ].x2 += 9999; r[ i ].y1 += 10000; r[ i ].y2 += 9999;
    }
    pos = 1;
    while ( pos < 20001 )
        pos <<= 1;
    for ( i = pos; i < pos * 2; i++ )
    {
        h[ 0 ][ i ].left = h[ 0 ][ i ].right = h[ 1 ][ i ].left = h[ 1 ][ i ].right = i - pos;
        h[ 0 ][ i ].data = h[ 1 ][ i ].data = h[ 0 ][ i ].buff = h[ 1 ][ i ].buff = 0;
    }
    for ( i = pos - 1; i >= 1; i-- )
    {
        h[ 0 ][ i ].left = h[ 1 ][ i ].left = h[ 0 ][ i * 2 ].left;
        h[ 0 ][ i ].right = h[ 1 ][ i ].right = h[ 0 ][ i * 2 + 1 ].right;
        h[ 0 ][ i ].data = h[ 1 ][ i ].data = h[ 0 ][ i ].buff = h[ 1 ][ i ].buff = 0;
    }
}


void work( )
{
    int i, t;
    __int64 x1 = 30000, x2 = 30000, y1 = -1, y2 = -1, xx, yy, maxx = 0, maxy = 0, tx, ty, x3 = 30000, x4 = 30000, y3 = -1, y4 = -1, maxn = 0, xx1, yy1, xx3, yy3;
    for ( i = 0; i < n; i++ )
    {
        add( h[ 0 ], 1, r[ i ].x1, r[ i ].x2 );
        add( h[ 1 ], 1, r[ i ].y1, r[ i ].y2 );
    }
    for ( i = 0; i < 20001; i++ )
    {
        t = query( h[ 0 ], 1, i, i );
        if ( t == n )
        {
            if ( x1 > i ) x1 = i;
            if ( x2 > i ) x2 = i;
            if ( y1 < i ) y1 = i;
            if ( y2 < i ) y2 = i;
        }
        if ( t >= n - 1 )
        {
            if ( x1 > i ) x1 = i;
            if ( y1 < i ) y1 = i;
        }
    }
    for ( i = 0; i < 20001; i++ )
    {
        t = query( h[ 1 ], 1, i, i );
        if ( t == n )
        {
            if ( x3 > i ) x3 = i;
            if ( x4 > i ) x4 = i;
            if ( y3 < i ) y3 = i;
            if ( y4 < i ) y4 = i;
        }
        if ( t >= n - 1 )
        {
            if ( x3 > i ) x3 = i;
            if ( y3 < i ) y3 = i;
        }
    }
    if ( x1 == 30000 || x3 == 30000 )
    {
        printf("0\n");
        return ;
    }
    //printf("!%d %d %d %d\n%d %d %d %d\n", x1, y1, x2, y2, x3, y3, x4, y4);
    if ( x2 == 30000 )
    {
        for ( i = x1; i < 20001; i++ )
            if ( query( h[ 0 ], 1, i, i ) < n - 1 )
                break;
        xx1 = x1; yy1 = i;
        for ( i = y1; i >= 0; i-- )
            if ( query( h[ 0 ], 1, i, i ) < n - 1 )
                break;
        x1 = i;
    }
    if ( x4 == 30000 )
    {
        for ( i = x1; i < 20001; i++ )
            if ( query( h[ 0 ], 1, i, i ) < n - 1 )
                break;
        xx1 = x1; yy1 = i;
        for ( i = y1; i >= 0; i-- )
            if ( query( h[ 0 ], 1, i, i ) < n - 1 )
                break;
        x1 = i;
    }
    for ( i = 0; i < n; i++ )
    {
        xx = r[ i ].x1;
        yy = r[ i ].x2;//printf("%d %d\n", xx, x2);
        if ( x2 == 30000 )
        {
            if ( yy < x1 || xx > y1 )
                tx = y1 - x1 + 1;
            else
                if ( xx >= x1 )
                    tx = xx - x1;
                else
                    tx = y1 - yy;
        }
        else
        {
            if ( xx < x2 )
            {
                if ( yy > y2 )
                    tx = y2 - x2 + 1;
                else
                    tx = y1 - x2 + 1;
            }
            if ( xx == x2 )
            {
                if ( yy > y2 )
                    tx = y2 - x1 + 1;
                else
                    tx = y1 - x1 + 1;
            }
        }
        xx = r[ i ].y1;
        yy = r[ i ].y2;
        if ( x4 == 30000 )
        {
            if ( yy < x3 || yy > y3 )
                ty = y3 - x3 + 1;
            else
                if ( xx >= x3 )
                    ty = xx - x3;
                else
                    ty = y3 - yy;
        }
        else
        {
            if ( xx < x4 )
            {
                if ( yy > y4 )
                    ty = y4 - x4 + 1;
                else
                    ty = y3 - x4 + 1;
            }
            if ( xx == x4 )
            {
                if ( yy > y4 )
                    ty = y4 - x3 + 1;
                else
                    ty = y3 - x3 + 1;
            }
        }
        if ( maxn < tx * ty )
        {
            maxn = tx * ty;
            //printf("%d %d %d\n", tx, ty, maxn);
        }
    }
    printf("%I64d\n", maxn);
}

inline void iswap(Node &a,Node &b){
    Node tmp = a;
    a = b;
    b = tmp;
}
inline Node get(Node a,Node b){
    if(a.x1 > b.x1) iswap(a,b);
    int x1,y1,x2,y2;
    if(b.x1 > a.x2 || b.y1 > a.y2 || b.y2 < a.y1) {
        return Node(0,0,0,0,false);
    }
    x1 = b.x1;
    x2 = min(a.x2,b.x2);
    y1 = a.y1;
    y2 = a.y2;
    if(a.y1 <= b.y1 && b.y1 <= a.y2){
        y1 = b.y1;
    }
    if(a.y1 <= b.y2 && b.y2 <= a.y2){
        y2 = b.y2;
    }
    return Node(x1,y1,x2,y2,true);
}
void make(){
    left[1] = node[1];
    for(int i = 2 ; i <= n ; i ++){
        left[i] = get(left[i - 1],node[i]);
    }
    right[n] = node[n];
    for(int i = n - 1 ; i >= 1 ; i --){
        right[i] = get(right[i + 1],node[i]);
    }
}
inline void solve(){
    int ans = 0;
    ans = max(left[n - 1].area(),right[2].area());
    for(int i = 2 ; i < n ; i ++){
        res[i] = get(left[i - 1],right[i + 1]);
        int tmp = res[i].area();
        if(ans < tmp) ans = tmp;
    }
    printf("%d\n",ans);
}
int main(){
    //freopen("in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i = 1 ; i <= n ; i ++){
            scanf("%d%d%d%d",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2);
            if(node[i].x1 > node[i].x2) swap(node[i].x1,node[i].x2);
            if(node[i].y1 > node[i].y2) swap(node[i].y1,node[i].y2);
            node[i].flag = true;
        }
        make();
        solve();
    }
}
